package flexo.graphic;

import flexo.common.LogMsgType;

public class ShaderParam
{
	public enum Type
	{
		TEXTURE,
		INT,
		FLOAT,
		VECTOR,
		COLOR,
		MATRIX
	}
	
	protected String name;
	protected Type type;
	protected java.lang.Object value;
	
	ShaderParam(String name, Type type)
	{
		this.name = name;
		this.type = type;
		value = null;
	}
	
	protected void wrongParamType()
	{
		flexo.Kernel.log("flexo.graphic.ShaderParam", "Asigning wrong type value to shader parameter '"+name+"'.", LogMsgType.WARNING);
	}
	
	public void setValue(Integer value)
	{
		if (type == Type.INT)
		{
			this.value = value;
		}
		else
		{
			wrongParamType();
		}
	}
	
	public void setValue(Float value)
	{
		if (type == Type.FLOAT)
		{
			this.value = value;
		}
		else
		{
			wrongParamType();
		}
	}
	
	public void setValue(flexo.math.Vector value)
	{
		if (type == Type.VECTOR)
		{
			this.value = value;
		}
		else
		{
			wrongParamType();
		}
	}
	
	public void setValue(Color value)
	{
		if (type == Type.COLOR)
		{
			this.value = value;
		}
		else
		{
			wrongParamType();
		}
	}
	
	public void setValue(flexo.math.Matrix value)
	{
		if (type == Type.MATRIX)
		{
			this.value = value;
		}
		else
		{
			wrongParamType();
		}
	}
	
	public void setValue(String textureName)
	{
		if (type == Type.TEXTURE)
		{
			Texture t = (Texture)value;
			if (value != null)
			{				
				t.remove();
				value = null;
			}
			
			flexo.graphic.GraphicSystem gs = (flexo.graphic.GraphicSystem)flexo.Kernel.getSystem(flexo.graphic.GraphicSystem.ID);
			t = gs.texturePool.get(textureName);
			t.grab();
			value = t;
		}
		else
		{
			wrongParamType();
		}
	}
	
	void apply(Shader s)
	{
		if (value == null)
		{
			flexo.Kernel.log("flexo.graphic.ShaderParam","Shader parameter '"+name+"' hasn't been initialized.", LogMsgType.WARNING);
		}
		
		switch(type)
		{
		case INT:
			s.set(name, ((Integer)value).intValue());
			break;
		case FLOAT:
			s.set(name, ((Float)value).floatValue());
			break;
		case VECTOR:
			s.set(name, ((flexo.math.Vector)value));
			break;
		case COLOR:
			s.set(name, ((Color)value));
			break;
		case MATRIX:
			s.set(name, ((flexo.math.Matrix)value),false);
			break;
		case TEXTURE:
			s.set(name, ((Texture)value));
		}
	}
	
	void remove()
	{
		if (type == Type.TEXTURE)
		{
			((Texture)value).remove();
		}
	}
}
